package player

import (
	"GameServer/Common/data"
	"GameServer/Common/utils"
	"GameServer/Game/advert"
	"GameServer/Game/errors"
	"GameServer/Game/lib"
	"GameServer/Game/m"
	"GameServer/Game/sp"
	"fmt"

	log "github.com/sirupsen/logrus"
)

// 8001 卡牌 进入游戏
func (p *Player) CardGameEnterRequest(req *sp.CardGameEnterRequest) (res *sp.CardGameEnterResponse, err error) {
	cardGame, err := lib.NewCardGame(p.User, req.Gid, req.MonsterTid)
	if err != nil {
		res = &sp.CardGameEnterResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	res = &sp.CardGameEnterResponse{
		Monster:      lib.FormatCardMonsterSp(cardGame.Monster),
		CardList:     lib.FormatCardSps(cardGame.Cards),
		Stone:        cardGame.Stone,
		Round:        cardGame.Round,
		PlayerShield: cardGame.PlayerShield,
		GridId:       req.Gid,
	}

	nGuide := p.User.GetNewGuide()

	if nGuide.FirstCardMonsterGold == false && req.MonsterTid == data.NewGuildMonsterTid {
		uProp, _, _, err := lib.GiveGoodsByKv("CardGameEnterRequest", p.User, m.BaseKV{Key: data.GlobalEnum.Gold, Val: 20000}, p.Send)
		if err != nil {
			log.WithFields(log.Fields{
				"uid":    p.User.Uid.Hex(),
				"data":   "20000",
				"method": "CardGameEnterRequest",
			}).Debug("给金币失败")
			return res, err
		}
		// 有成就完成，进行通知
		achLst := lib.AchievComplete(p.User)
		if len(achLst) > 0 {
			p.Send(&sp.AchievementNoticeRequest{
				Lst: achLst,
			})
		}
		if uProp != nil {
			p.TimelyUpdateProp(req.GetType(), uProp)
			utils.AsyncFunc(func() {
				p.UpdateProp(req.GetType(), uProp)
			})
		}
		nGuide.FirstCardMonsterGold = true
	}
	return
}

// 8002 卡牌  玩家使用手上的卡牌
func (p *Player) CardGameUseCardRequest(req *sp.CardGameUseCardRequest) (res *sp.CardGameUseCardResponse, err error) {
	cardGame := p.User.GetCardGame()
	hattrs, useCarduProp, err := lib.UseCard(p.User, cardGame, req.CardId, p.Send)

	if err != nil {
		res = &sp.CardGameUseCardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	if useCarduProp != nil {
		// p.TimelyUpdateProp(req.GetType(), useCarduProp)
		p.UpdateProp(req.GetType(), useCarduProp)
	}

	var monsterhurtSum int64 = 0

	for _, hurtInfo := range hattrs {
		if int64(hurtInfo.Target) != data.CardEffectTargetEnum.Player {
			continue
		}
		if int64(hurtInfo.HurtType) != data.CardHurtTypeEnum.Hurt {
			continue
		}
		hurtNum := int64(hurtInfo.Val)
		if hurtNum > 0 {
			monsterhurtSum = monsterhurtSum + hurtNum
		}
	}

	defer cardGame.Update(cardGame)
	if monsterhurtSum > 0 {
		if monsterhurtSum >= p.User.Gold {
			if cardGame.Status == 0 {
				cardGame.Status = 2 // 失败
			}
			monsterhurtSum = p.User.Gold
		}
		uProp, err := lib.Cost("CardGameUseCardRequest", p.User, []m.BaseKV{{Key: data.GlobalEnum.Gold, Val: monsterhurtSum}})
		if err != nil {
			res = &sp.CardGameUseCardResponse{
				Errcode: errors.ErrCode(err),
			}
			return res, err
		}

		p.TimelyUpdateProp(req.GetType(), uProp)
		utils.AsyncFunc(func() {
			p.UpdateProp(req.GetType(), uProp)
		})

		cardGame.LossGold += monsterhurtSum
	}

	if cardGame.Monster.Hp <= 0 {
		cardGame.Status = 1
		// 成就，记录击杀怪物次数
		lib.AddAchievProgress(p.User, data.AchievementType.Monster_kill, 1)
		// 委托活动，杀怪。
		lib.CalcHonor(p.User, data.EntrType.Guard, data.EntrEnum.KillMonster, cardGame.Monster.Tid)
		if num := lib.EntrustCheck(p.User); num > 0 {
			utils.AsyncFunc(func() {
				p.Send(&sp.EntrustNoticeRequest{
					Num: num,
				})
			})
		}
	}

	res = &sp.CardGameUseCardResponse{
		CardId:           req.CardId,
		Stone:            cardGame.Stone,
		Status:           cardGame.Status,
		CardAtt:          lib.FormatHurtAttrSps(hattrs),
		CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
		Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
		NextCardNumMinus: cardGame.NextCardNumMinus,
		PlayerShield:     cardGame.PlayerShield,
		CardList:         lib.FormatCardSps(cardGame.Cards),
		LossGold:         cardGame.LossGold,
	}

	if cardGame.Status == 1 {
		// 战斗胜利给公会积分
		if p.User.UnionId != "" {
			uProp, _, _, err := lib.GiveGoodsByKv("CardGameUseCardRequest", p.User, m.BaseKV{Key: data.GlobalEnum.Union, Val: 1}, p.Send)
			if err != nil {
				log.WithFields(log.Fields{
					"data":   m.BaseKV{Key: data.GlobalEnum.Union, Val: 1},
					"uid":    p.User.Uid.Hex(),
					"method": "CardGameUseCardRequest",
				}).Error("给公会积分失败")
			} else {
				// 有成就完成，进行通知
				achLst := lib.AchievComplete(p.User)
				if len(achLst) > 0 {
					p.Send(&sp.AchievementNoticeRequest{
						Lst: achLst,
					})
				}

				p.TimelyUpdateProp(req.GetType(), uProp)
				utils.AsyncFunc(func() {
					p.UpdateProp(req.GetType(), uProp)
				})
			}
		}
		if cardGame.Gid >= 0 {
			// 战斗失败，清怪
			gridInfo := lib.ClearLayerMonster(p.User, cardGame, 1)
			res.GInfo = lib.FormartGridInfoSp(gridInfo)
			// 怪死了，解锁周围的格子
			grids, err := lib.MonsterUnlockBrick(p.User, cardGame.Gid)
			if err == nil {
				res.GridList = lib.FormartGridInfoSps(grids)
			}
		}
	}

	return
}

// 8003 卡牌  回合结束
func (p *Player) CardGameRoundEndRequest(req *sp.CardGameRoundEndRequest) (res *sp.CardGameRoundEndResponse, err error) {
	cardGame := p.User.GetCardGame()
	monsterhurtSum, hattrs, err := lib.RoundEnd(p.User, p.User.Gold, cardGame)
	if err != nil {
		res = &sp.CardGameRoundEndResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	defer cardGame.Update(cardGame)
	if monsterhurtSum > 0 {
		if monsterhurtSum >= p.User.Gold {
			if cardGame.Status == 0 {
				cardGame.Status = 2 // 失败
			}
			monsterhurtSum = p.User.Gold
		}
		uProp, err := lib.Cost("CardGameRoundEndRequest", p.User, []m.BaseKV{{Key: data.GlobalEnum.Gold, Val: monsterhurtSum}})
		if err != nil {
			res = &sp.CardGameRoundEndResponse{
				Errcode: errors.ErrCode(err),
			}
			return res, err
		}

		p.TimelyUpdateProp(req.GetType(), uProp)
		utils.AsyncFunc(func() {
			p.UpdateProp(req.GetType(), uProp)
		})

		cardGame.LossGold += monsterhurtSum
	}

	if cardGame.Status == 0 {
		cardGame.Stone += data.CardManaEnum.ManaPerTurn
	}

	res = &sp.CardGameRoundEndResponse{
		Status:           cardGame.Status,
		Round:            cardGame.Round,
		Stone:            cardGame.Stone,
		CardAtt:          lib.FormatHurtAttrSps(hattrs),
		CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
		Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
		CardList:         lib.FormatCardSps(cardGame.Cards),
		NextCardNumMinus: cardGame.NextCardNumMinus,
		PlayerShield:     cardGame.PlayerShield,
		LossGold:         cardGame.LossGold,
	}

	if cardGame.Status == 1 { // 战斗胜利给公会积分
		if p.User.UnionId != "" {
			uProp, _, _, err := lib.GiveGoodsByKv("CardGameUseCardRequest", p.User, m.BaseKV{Key: data.GlobalEnum.Union, Val: 1}, p.Send)
			if err != nil {
				log.WithFields(log.Fields{
					"data":   m.BaseKV{Key: data.GlobalEnum.Union, Val: 1},
					"uid":    p.User.Uid.Hex(),
					"method": "CardGameUseCardRequest",
				}).Error("给公会积分失败")
			} else {
				// 有成就完成，进行通知
				achLst := lib.AchievComplete(p.User)
				if len(achLst) > 0 {
					p.Send(&sp.AchievementNoticeRequest{
						Lst: achLst,
					})
				}
				p.TimelyUpdateProp(req.GetType(), uProp)
				utils.AsyncFunc(func() {
					p.UpdateProp(req.GetType(), uProp)
				})
			}
		}
		// 清理怪
		gridInfo := lib.ClearLayerMonster(p.User, cardGame, 1)
		res.GInfo = lib.FormartGridInfoSp(gridInfo)
		// 怪死了，解锁周围的格子
		grids, err := lib.MonsterUnlockBrick(p.User, cardGame.Gid)
		if err == nil {
			res.GridList = lib.FormartGridInfoSps(grids)
		}
	}
	return
}

// 8004 卡牌 主动 退出游戏 不删除怪
func (p *Player) CardGameOverRequest(req *sp.CardGameOverRequest) (res *sp.CardGameOverResponse) {
	cardGame := p.User.GetCardGame()
	// cardGame.Status = 3
	// // 把格子物品删除 ，相当于把怪物删除
	// cardGame.Update(cardGame)

	// var isBossMonster bool = false
	// // 获取怪物信息---判断是否是挖宝BOSS
	// monsterTpl, ok := data.Get("CardMonsters", uint64(cardGame.Monster.Tid))
	// if ok {
	// 	monsterConfig := monsterTpl.(data.CardMonster) // 获得怪物配置表信息
	// 	if int64(monsterConfig.Type) == data.CardMonsterTypeEnum.Boss {
	// 		isBossMonster = true
	// 	}
	// } else {
	// 	log.WithFields(log.Fields{
	// 		"Tid":    cardGame.Monster.Tid,
	// 		"uid":    p.User.Uid.Hex(),
	// 		"method": "CardGameRoundEndRequest",
	// 	}).Error("没有找到怪物配置信息")
	// }

	// if isBossMonster == false {
	// 	gridInfo, _ := p.User.GetGrid(cardGame.Gid)
	// 	gridInfo.Goods = nil
	// 	// 更新当前层 格子信息
	// 	p.User.GetLayer().UpdateGrid(gridInfo)
	// 	res = &sp.CardGameOverResponse{
	// 		GInfo: lib.FormartGridInfoSp(gridInfo),
	// 	}
	// 	return res
	// }
	var gridInfo *m.GridInfo = nil
	if cardGame.Gid >= 0 {
		gridInfo, _ = p.User.GetGrid(cardGame.Gid)
	}
	// 没有格子的怪，玩家退出，清除怪
	cardGame.Status = 1
	cardGame.Update(cardGame)

	res = &sp.CardGameOverResponse{
		GInfo: lib.FormartGridInfoSp(gridInfo),
	}
	return res
}

// 8005 获取卡牌游戏 信息（断线重连）
func (p *Player) CardGameInfoRequest(req *sp.CardGameInfoRequest) (res *sp.CardGameInfoResponse) {
	cardGame := p.User.GetCardGame()
	cardDeck := cardGame.GetCardDeck(p.User.Pos.LockBlockTid)
	magicBook := cardGame.GetMagicBookInfo()
	// 8005返回错误，标识没有上次断线的战斗记录，其他情况不会返回错误
	// 8005无论返不返回错误，都要携带魔法书和卡组信息给客户端
	if cardGame.Status != 0 {
		log.WithFields(log.Fields{
			"Status": cardGame.Status,
			"method": "CardGameInfoRequest",
		}).Debug("8005战斗请求")
		res = &sp.CardGameInfoResponse{
			Errcode:       data.Errcode.NotFound,
			MagicBookInfo: lib.FormatCardGameMagicBookInfo(magicBook),
			CardDeck:      lib.FormatCardGameCardDeckInfo(cardDeck),
		}
		return
	}
	if magicBook.Status == 1 {
		if magicBook.CardLst == nil || len(magicBook.CardLst) == 0 {
			magicBook.Status = 0
			cardGame.MagicBook = magicBook
		}
	}
	if cardGame.Monster.Tid == 240000 && cardGame.Round == 0 {
		cardGame.Round = 3
	}
	cardGame.Update(cardGame)

	res = &sp.CardGameInfoResponse{
		Round:            cardGame.Round,
		Stone:            cardGame.Stone,
		CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
		Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
		CardList:         lib.FormatCardSps(cardGame.Cards),
		NextCardNumMinus: cardGame.NextCardNumMinus,
		PlayerShield:     cardGame.PlayerShield,
		GridId:           cardGame.Gid,
		MagicBookInfo:    lib.FormatCardGameMagicBookInfo(magicBook),
		CardDeck:         lib.FormatCardGameCardDeckInfo(cardDeck),
	}
	return
}

// 8006 领取卡牌游戏奖励
func (p *Player) CardGameRewardsRequest(req *sp.CardGameRewardsRequest) (res *sp.CardGameRewardsResponse, err error) {
	cardGame := p.User.GetCardGame()
	if cardGame.Status != 1 {
		res = &sp.CardGameRewardsResponse{
			Errcode: data.Errcode.NotFound,
		}
		return
	}
	isFirstKill, uProp, resGoods, boxResList, err := lib.CardGameRewards("CardGameRewardsRequest", p.User, cardGame, p.Send)
	if err != nil {
		res = &sp.CardGameRewardsResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	// 有成就完成，进行通知
	achLst := lib.AchievComplete(p.User)
	if len(achLst) > 0 {
		p.Send(&sp.AchievementNoticeRequest{
			Lst: achLst,
		})
	}

	monsterID := cardGame.Monster.Tid
	// 新兵特训
	lib.RecruitTrainMsg(p.User.Uid.Hex(), 0, 0, monsterID, p.Send)
	if isFirstKill {
		lib.DoneBossPack(p.User, monsterID)
	}
	bp, _ := lib.GetBossPack(p.User)

	res = &sp.CardGameRewardsResponse{
		Res:        lib.FormatGoodsInfoSps(resGoods),
		BoxRes:     lib.FormatBoxResSps(boxResList),
		BossPayLst: lib.FormatBossPacktSps(bp),
	}
	p.TimelyUpdateProp(req.GetType(), uProp)
	utils.AsyncFunc(func() {
		p.UpdateProp(req.GetType(), uProp)
	})
	return
}

// 8007 获取击杀怪物信息
func (p *Player) CardMonsterKillInfoRequest(req *sp.CardMonsterKillInfoRequest) (res *sp.CardMonsterKillInfoResponse, err error) {
	cardGame := p.User.GetCardGame()
	res = &sp.CardMonsterKillInfoResponse{
		KillList: lib.FormatCardGameKillMonsterSps(cardGame.KillMonsters),
	}
	return
}

// 8008 金币击杀
func (p *Player) CardGameGoldStrikeRequest(req *sp.CardGameGoldStrikeRequest) (res *sp.CardGameGoldStrikeResponse, err error) {
	// 首先进行金币校验
	monsterTid := req.MonsterTid
	tpl, ok := data.Get("CardMonsters", uint64(monsterTid))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, fmt.Sprintf("没有找到怪物信息，tid:%d", monsterTid))
		return
	}
	monsterT := tpl.(data.CardMonster)
	if int64(monsterT.Type) != data.CardMonsterTypeEnum.Normal {
		err = errors.NewErrcode(data.Errcode.ServerErr, "不可速杀")
		return
	}
	if int64(monsterT.QuickKillLimit) > p.User.Gold {
		err = errors.NewErrcode(data.Errcode.NoGold, "钱不够")
		return
	}
	cardGame := p.User.GetCardGame()
	if cardGame.Status != 1 {
		cardGame, err = lib.NewCardGame(p.User, req.Gid, monsterTid)
		if err != nil {
			res = &sp.CardGameGoldStrikeResponse{
				Errcode: errors.ErrCode(err),
			}
			return
		}
	}

	cost := m.BaseKV{Key: data.GlobalEnum.Gold, Val: int64(monsterT.QuickKillLimit)}
	uProp, err := lib.Cost("CardGameGoldStrike", p.User, []m.BaseKV{cost})
	if err != nil {
		return
	}
	p.TimelyUpdateProp(req.GetType(), uProp)
	utils.AsyncFunc(func() {
		p.UpdateProp(req.GetType(), uProp)
	})

	cardGame.Round = 0 // 金币击杀回合数设为0
	_, uProp, resGoods, boxResList, err := lib.CardGameRewards("CardGameGoldStrikeRequest", p.User, cardGame, p.Send)
	if err != nil {
		res = &sp.CardGameGoldStrikeResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	p.TimelyUpdateProp(req.GetType(), uProp)
	utils.AsyncFunc(func() {
		p.UpdateProp(req.GetType(), uProp)
	})
	gridInfo, _ := p.User.GetGrid(cardGame.Gid)
	if cardGame.Status != 0 {
		// 更新当前层 格子信息
		gridInfo.Goods = nil
		p.User.GetLayer().UpdateGrid(gridInfo)
		if cardGame.Status == 1 || cardGame.Status == 4 {
			// 战斗胜利给公会积分
			if p.User.UnionId != "" {
				uProp, _, _, err := lib.GiveGoodsByKv("CardGameUseCardRequest", p.User, m.BaseKV{Key: data.GlobalEnum.Union, Val: 1}, p.Send)
				if err != nil {
					log.WithFields(log.Fields{
						"data":   m.BaseKV{Key: data.GlobalEnum.Union, Val: 1},
						"uid":    p.User.Uid.Hex(),
						"method": "CardGameUseCardRequest",
					}).Error("给公会积分失败")
				} else {
					// 有成就完成，进行通知
					achLst := lib.AchievComplete(p.User)
					if len(achLst) > 0 {
						p.Send(&sp.AchievementNoticeRequest{
							Lst: achLst,
						})
					}
					p.TimelyUpdateProp(req.GetType(), uProp)
					utils.AsyncFunc(func() {
						p.UpdateProp(req.GetType(), uProp)
					})
				}
			}
		}
	}

	// 委托活动，杀怪。
	lib.CalcHonor(p.User, data.EntrType.Guard, data.EntrEnum.KillMonster, req.MonsterTid)
	if num := lib.EntrustCheck(p.User); num > 0 {
		utils.AsyncFunc(func() {
			p.Send(&sp.EntrustNoticeRequest{
				Num: num,
			})
		})
	}
	// 成就，记录金币击杀怪物次数。
	lib.AddAchievProgress(p.User, data.AchievementType.Gold_kill, 1)
	// 有成就完成，进行通知
	achLst := lib.AchievComplete(p.User)
	if len(achLst) > 0 {
		p.Send(&sp.AchievementNoticeRequest{
			Lst: achLst,
		})
	}
	res = &sp.CardGameGoldStrikeResponse{
		Res:     lib.FormatGoodsInfoSps(resGoods),
		BoxRes:  lib.FormatBoxResSps(boxResList),
		GInfo:   lib.FormartGridInfoSp(gridInfo),
		Monster: lib.FormatCardMonsterSp(cardGame.Monster),
	}

	// 怪死了，解锁周围的格子
	grids, err := lib.MonsterUnlockBrick(p.User, cardGame.Gid)
	if err == nil {
		res.GridList = lib.FormartGridInfoSps(grids)
	}
	return
}

// 8009 处理魔法书
func (p *Player) CardGameDuelMagicBookRequest(req *sp.CardGameDuelMagicBookRequest) (res *sp.CardGameDuelMagicBookResponse, err error) {
	us := p.User
	// funcType := req.FuncTyp //  0-获取新魔法书 1-重置 2-确认 3-丢弃
	lockBlockTid := p.User.Pos.LockBlockTid
	selectId := req.CardId
	gridId := req.GridId
	cardGame := p.User.GetCardGame()
	cardDeck := cardGame.GetCardDeck(lockBlockTid)
	// magicBook := cardGame.GetMagicBookInfo()

	switch req.FuncTyp {
	case 0: // 获取新魔法书
		err := lib.MagicBookGet(p.User, cardGame, gridId)
		if err != nil {
			res = &sp.CardGameDuelMagicBookResponse{
				ErrCode: errors.ErrCode(err),
			}
			return res, err
		}
		cardDeck = cardGame.GetCardDeck(lockBlockTid)
		magicBook := cardGame.GetMagicBookInfo()
		res = &sp.CardGameDuelMagicBookResponse{
			FuncTyp:       req.FuncTyp,
			MagicBookInfo: lib.FormatCardGameMagicBookInfo(magicBook),
			CardDeck:      lib.FormatCardGameCardDeckInfo(cardDeck),
		}
		return res, nil
	case 1: // 重置
		advert.Module.AddAdCnt(data.AdCard)                         // 统计换卡广告
		advert.Module.AddAdUser(us.Uid.Hex(), us.Name, data.AdCard) // 统计换卡广告
		err := lib.MagicBookReset(p.User, cardGame, gridId)
		if err != nil {
			res = &sp.CardGameDuelMagicBookResponse{
				ErrCode: errors.ErrCode(err),
			}
			return res, err
		}
		cardDeck = cardGame.GetCardDeck(lockBlockTid)
		magicBook := cardGame.GetMagicBookInfo()
		res = &sp.CardGameDuelMagicBookResponse{
			FuncTyp:       req.FuncTyp,
			MagicBookInfo: lib.FormatCardGameMagicBookInfo(magicBook),
			CardDeck:      lib.FormatCardGameCardDeckInfo(cardDeck),
		}
		return res, nil
	case 2: // 确认
		err := lib.MagicBookAccept(p.User, cardGame, selectId, gridId)
		if err != nil {
			res = &sp.CardGameDuelMagicBookResponse{
				ErrCode: errors.ErrCode(err),
			}
			return res, err
		}
		// 更新当前层 格子信息
		gridInfo, _ := p.User.GetGrid(gridId)
		gridInfo.Goods = nil
		p.User.GetLayer().UpdateGrid(gridInfo)
		// 更新层级信息
		r := p.User.GetLayer().GridList
		defer p.User.GetLayer().UpdateGridByMap(r)

		cardDeck = cardGame.GetCardDeck(lockBlockTid)
		magicBook := cardGame.GetMagicBookInfo()
		res = &sp.CardGameDuelMagicBookResponse{
			FuncTyp:       req.FuncTyp,
			MagicBookInfo: lib.FormatCardGameMagicBookInfo(magicBook),
			CardDeck:      lib.FormatCardGameCardDeckInfo(cardDeck),
			GInfo:         lib.FormartGridInfoSp(gridInfo),
		}
		return res, nil
	case 3: // 丢弃
		lib.MaigcBookAbandon(cardGame, gridId)
		// 更新当前层 格子信息
		gridInfo, _ := p.User.GetGrid(gridId)
		gridInfo.Goods = nil
		p.User.GetLayer().UpdateGrid(gridInfo)
		// 更新层级信息
		r := p.User.GetLayer().GridList
		defer p.User.GetLayer().UpdateGridByMap(r)

		cardDeck = cardGame.GetCardDeck(lockBlockTid)
		magicBook := cardGame.GetMagicBookInfo()
		res = &sp.CardGameDuelMagicBookResponse{
			FuncTyp:       req.FuncTyp,
			MagicBookInfo: lib.FormatCardGameMagicBookInfo(magicBook),
			CardDeck:      lib.FormatCardGameCardDeckInfo(cardDeck),
			GInfo:         lib.FormartGridInfoSp(gridInfo),
		}
		return res, nil
	default:
		errMsg := fmt.Sprintf("没有对应的魔法书操作 %d", req.FuncTyp)
		fmt.Println(errMsg)
		err := errors.NewErrcode(data.Errcode.ServerErr, errMsg)
		res = &sp.CardGameDuelMagicBookResponse{
			ErrCode: errors.ErrCode(err),
		}
		return res, nil
	}
}

// 8010 获得卡组信息
func (p *Player) CardGameGetCardDeckRequest(req *sp.CardGameGetCardDeckRequest) (res *sp.CardGameGetCardDeckResponse, err error) {
	cardGame := p.User.GetCardGame()
	cardDeck := cardGame.GetCardDeck(p.User.Pos.LockBlockTid)
	// magicBook := cardGame.GetMagicBookInfo()
	res = &sp.CardGameGetCardDeckResponse{
		ErrCode:  0,
		CardDeck: lib.FormatCardGameCardDeckInfo(cardDeck),
		// MagicBookInfo: lib.FormatCardGameMagicBookInfo(magicBook),
	}
	return res, nil
}

// 8020 卡牌 超级指令
func (p *Player) CardGameDevCommandRequest(req *sp.CardGameDevCommandRequest) (res *sp.CardGameDevCommandResponse, err error) {
	if p.User.SuperAccount != 1 {
		res = &sp.CardGameDevCommandResponse{
			FuncTyp: req.FuncTyp,
			ErrCode: 999,
		}
		return
	}
	cardGame := p.User.GetCardGame()
	funcTyp := req.FuncTyp
	vals := req.Vals
	if funcTyp == 0 {
		// UseCard
		if vals == nil || len(vals) != 1 {
			res = &sp.CardGameDevCommandResponse{
				FuncTyp: funcTyp,
				ErrCode: 999,
			}
			return
		}
		cardTid := vals[0]
		hattrs, useCarduProp, err := lib.UseCardByCardTid(p.User, cardGame, cardTid, p.Send)
		if err != nil {
			res = &sp.CardGameDevCommandResponse{
				FuncTyp: funcTyp,
				ErrCode: errors.ErrCode(err),
			}
			return res, err
		}
		if useCarduProp != nil {
			// p.TimelyUpdateProp(req.GetType(), useCarduProp)
			p.UpdateProp(req.GetType(), useCarduProp)
		}
		var monsterhurtSum int64 = 0

		for _, hurtInfo := range hattrs {
			if int64(hurtInfo.Target) != data.CardEffectTargetEnum.Player {
				continue
			}
			if int64(hurtInfo.HurtType) != data.CardHurtTypeEnum.Hurt {
				continue
			}
			hurtNum := int64(hurtInfo.Val)
			if hurtNum > 0 {
				monsterhurtSum = monsterhurtSum + hurtNum
			}
		}

		if monsterhurtSum > 0 {
			if monsterhurtSum >= p.User.Gold {
				if cardGame.Status == 0 {
					cardGame.Status = 2 // 失败
				}
				monsterhurtSum = p.User.Gold
			}
			uProp, err := lib.Cost("CardGameUseCardRequest", p.User, []m.BaseKV{{Key: data.GlobalEnum.Gold, Val: monsterhurtSum}})
			if err != nil {
				res = &sp.CardGameDevCommandResponse{
					FuncTyp: funcTyp,
					ErrCode: errors.ErrCode(err),
				}
				return res, err
			}

			p.TimelyUpdateProp(req.GetType(), uProp)
			utils.AsyncFunc(func() {
				p.UpdateProp(req.GetType(), uProp)
			})
		}

		if cardGame.Monster.Hp <= 0 {
			cardGame.Status = 1
			// 成就，记录击杀怪物次数
			lib.AddAchievProgress(p.User, data.AchievementType.Monster_kill, 1)
			// 委托活动，杀怪。
			lib.CalcHonor(p.User, data.EntrType.Guard, data.EntrEnum.KillMonster, cardGame.Monster.Tid)
			if num := lib.EntrustCheck(p.User); num > 0 {
				utils.AsyncFunc(func() {
					p.Send(&sp.EntrustNoticeRequest{
						Num: num,
					})
				})
			}
		}

		res = &sp.CardGameDevCommandResponse{
			FuncTyp:          funcTyp,
			Stone:            cardGame.Stone,
			Status:           cardGame.Status,
			CardAtt:          lib.FormatHurtAttrSps(hattrs),
			CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
			Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
			NextCardNumMinus: cardGame.NextCardNumMinus,
			PlayerShield:     cardGame.PlayerShield,
			CardList:         lib.FormatCardSps(cardGame.Cards),
		}

		if cardGame.Status != 0 {
			gridInfo := lib.ClearLayerMonster(p.User, cardGame, 1)
			res.GInfo = lib.FormartGridInfoSp(gridInfo)

			if cardGame.Status == 1 {
				// 战斗胜利给公会积分
				if p.User.UnionId != "" {
					uProp, _, _, err := lib.GiveGoodsByKv("CardGameUseCardRequest", p.User, m.BaseKV{Key: data.GlobalEnum.Union, Val: 1}, p.Send)
					if err != nil {
						log.WithFields(log.Fields{
							"data":   m.BaseKV{Key: data.GlobalEnum.Union, Val: 1},
							"uid":    p.User.Uid.Hex(),
							"method": "CardGameUseCardRequest",
						}).Error("给公会积分失败")
					} else {
						// 有成就完成，进行通知
						achLst := lib.AchievComplete(p.User)
						if len(achLst) > 0 {
							p.Send(&sp.AchievementNoticeRequest{
								Lst: achLst,
							})
						}

						p.TimelyUpdateProp(req.GetType(), uProp)
						utils.AsyncFunc(func() {
							p.UpdateProp(req.GetType(), uProp)
						})
					}
				}
			}
		}
		return res, nil
	} else if funcTyp == 1 {
		// SetMana
		if vals == nil || len(vals) != 1 {
			res = &sp.CardGameDevCommandResponse{
				FuncTyp: funcTyp,
				ErrCode: 999,
			}
			return
		} else {
			cardGame.Stone = vals[0]
			cardGame.Update(cardGame)
			res = &sp.CardGameDevCommandResponse{
				FuncTyp:          funcTyp,
				Status:           cardGame.Status,
				Stone:            cardGame.Stone,
				CardAtt:          nil,
				CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
				Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
				NextCardNumMinus: cardGame.NextCardNumMinus,
				PlayerShield:     cardGame.PlayerShield,
				CardList:         lib.FormatCardSps(cardGame.Cards),
			}
			return res, nil
		}
	} else if funcTyp == 2 {
		// SetMonsterHp
		if vals == nil || len(vals) != 1 {
			res = &sp.CardGameDevCommandResponse{
				FuncTyp: funcTyp,
				ErrCode: 999,
			}
			return
		} else {
			cardGame.Monster.Hp = vals[0]
			cardGame.Update(cardGame)
			res = &sp.CardGameDevCommandResponse{
				FuncTyp:          funcTyp,
				Status:           cardGame.Status,
				Stone:            cardGame.Stone,
				CardAtt:          nil,
				CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
				Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
				NextCardNumMinus: cardGame.NextCardNumMinus,
				PlayerShield:     cardGame.PlayerShield,
				CardList:         lib.FormatCardSps(cardGame.Cards),
			}
			return res, nil
		}
	} else if funcTyp == 3 {
		// SetMonsterShield
		if vals == nil || len(vals) != 1 {
			res = &sp.CardGameDevCommandResponse{
				FuncTyp: funcTyp,
				ErrCode: 999,
			}
			return
		} else {
			cardGame.Monster.Shield = vals[0]
			cardGame.Update(cardGame)
			res = &sp.CardGameDevCommandResponse{
				FuncTyp:          funcTyp,
				Status:           cardGame.Status,
				Stone:            cardGame.Stone,
				CardAtt:          nil,
				CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
				Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
				NextCardNumMinus: cardGame.NextCardNumMinus,
				PlayerShield:     cardGame.PlayerShield,
				CardList:         lib.FormatCardSps(cardGame.Cards),
			}
			return res, nil
		}
	} else if funcTyp == 4 {
		// AddMonsterBuff
		if vals == nil || len(vals) != 1 {
			res = &sp.CardGameDevCommandResponse{
				FuncTyp: funcTyp,
				ErrCode: 999,
			}
			return
		} else {
			buffTid := vals[0]
			skillTpl, ok := data.Get("CardMonsterSkills", uint64(buffTid))
			if !ok {
				err = errors.NewErrcode(data.Errcode.ConfigNotFound, fmt.Sprintf("没有找到怪物技能信息，tid:%d", buffTid))
				return nil, err
			}
			skillT := skillTpl.(data.CardMonsterSkill)
			lib.MonsterBuff_Add(cardGame, skillT, 1, int64(skillT.StayRound))
			res = &sp.CardGameDevCommandResponse{
				FuncTyp:          funcTyp,
				Status:           cardGame.Status,
				Stone:            cardGame.Stone,
				CardAtt:          nil,
				CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
				Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
				NextCardNumMinus: cardGame.NextCardNumMinus,
				PlayerShield:     cardGame.PlayerShield,
				CardList:         lib.FormatCardSps(cardGame.Cards),
			}
			return res, nil
		}
	} else if funcTyp == 5 {
		// SetMBuffCD
		if vals == nil || len(vals) != 2 {
			res = &sp.CardGameDevCommandResponse{
				FuncTyp: funcTyp,
				ErrCode: 999,
			}
			return
		} else {
			buffTid := vals[0]
			cd := vals[1]
			theSkill, find := cardGame.Monster.Skills[buffTid]
			if find {
				theSkill.Cd = cd
				cardGame.Monster.Skills[buffTid] = theSkill
				res = &sp.CardGameDevCommandResponse{
					FuncTyp:          funcTyp,
					Status:           cardGame.Status,
					Stone:            cardGame.Stone,
					CardAtt:          nil,
					CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
					Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
					NextCardNumMinus: cardGame.NextCardNumMinus,
					PlayerShield:     cardGame.PlayerShield,
					CardList:         lib.FormatCardSps(cardGame.Cards),
				}
				return res, nil
			}
		}
	} else if funcTyp == 6 {
		// SetMBuffVal
		if vals == nil || len(vals) != 2 {
			res = &sp.CardGameDevCommandResponse{
				FuncTyp: funcTyp,
				ErrCode: 999,
			}
			return
		} else {
			buffTid := vals[0]
			val := vals[1]
			theSkill, find := cardGame.Monster.Skills[buffTid]
			if find {
				theSkill.Val = val
				cardGame.Monster.Skills[buffTid] = theSkill
				res = &sp.CardGameDevCommandResponse{
					FuncTyp:          funcTyp,
					Status:           cardGame.Status,
					Stone:            cardGame.Stone,
					CardAtt:          nil,
					CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
					Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
					NextCardNumMinus: cardGame.NextCardNumMinus,
					PlayerShield:     cardGame.PlayerShield,
					CardList:         lib.FormatCardSps(cardGame.Cards),
				}
				return res, nil
			}
		}
	} else if funcTyp == 7 {
		// SetMBuffStay
		if vals == nil || len(vals) != 2 {
			res = &sp.CardGameDevCommandResponse{
				FuncTyp: funcTyp,
				ErrCode: 999,
			}
			return
		} else {
			buffTid := vals[0]
			stayRound := vals[1]
			theSkill, find := cardGame.Monster.Skills[buffTid]
			if find {
				theSkill.StayRound = stayRound
				cardGame.Monster.Skills[buffTid] = theSkill
				res = &sp.CardGameDevCommandResponse{
					FuncTyp:          funcTyp,
					Status:           cardGame.Status,
					Stone:            cardGame.Stone,
					CardAtt:          nil,
					CardBuffs:        lib.FormatCardBuffSps(cardGame.CardBuffs),
					Monster:          lib.FormatCardMonsterSp(cardGame.Monster),
					NextCardNumMinus: cardGame.NextCardNumMinus,
					PlayerShield:     cardGame.PlayerShield,
					CardList:         lib.FormatCardSps(cardGame.Cards),
				}
				return res, nil
			}
		}
	}
	res = &sp.CardGameDevCommandResponse{
		FuncTyp: funcTyp,
		ErrCode: 999,
	}
	return res, nil
}

// 8011 卡牌 返回金币
func (p *Player) CardReturnGoodsRequest(req *sp.CardReturnGoodsRequest) (res *sp.CardReturnGoodsResponse, err error) {
	us := p.User
	if req.Typ == 2 {
		advert.Module.AddAdCnt(data.AdBattle)                         // 统计战斗失败广告
		advert.Module.AddAdUser(us.Uid.Hex(), us.Name, data.AdBattle) // 统计战斗失败广告
	}

	uProp, resGoods, boxResList, err := lib.CardReturnGoods("CardReturnGoodsRequest", us, req.Typ, p.Send)
	if err != nil {
		res = &sp.CardReturnGoodsResponse{
			ErrCode: errors.ErrCode(err),
		}
		return
	}

	res = &sp.CardReturnGoodsResponse{
		Res:    lib.FormatGoodsInfoSps(resGoods),
		BoxRes: lib.FormatBoxResSps(boxResList),
	}

	cardGame := us.GetCardGame()
	if cardGame.Gid >= 0 {
		gridInfo, _ := us.GetGrid(cardGame.Gid)
		res.GInfo = lib.FormartGridInfoSp(gridInfo)
	}

	p.TimelyUpdateProp(req.GetType(), uProp)
	utils.AsyncFunc(func() {
		p.UpdateProp(req.GetType(), uProp)
	})
	return res, nil
}

// 8012 卡牌 指定战斗怪进入战斗
func (p *Player) CardGameDesignatedEnterRequest(req *sp.CardGameDesignatedEnterRequest) (res *sp.CardGameDesignatedEnterResponse, err error) {
	cardGame, err := lib.NewCardGame(p.User, -1, req.MonsterTid)
	if err != nil {
		res = &sp.CardGameDesignatedEnterResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	res = &sp.CardGameDesignatedEnterResponse{
		Monster:      lib.FormatCardMonsterSp(cardGame.Monster),
		CardList:     lib.FormatCardSps(cardGame.Cards),
		Stone:        cardGame.Stone,
		Round:        cardGame.Round,
		PlayerShield: cardGame.PlayerShield,
	}

	nGuide := p.User.GetNewGuide()

	if !nGuide.FirstCardMonsterGold && req.MonsterTid == data.NewGuildMonsterTid {
		uProp, _, _, err := lib.GiveGoodsByKv("CardGameDesignatedEnterRequest", p.User, m.BaseKV{Key: data.GlobalEnum.Gold, Val: 20000}, p.Send)
		if err != nil {
			log.WithFields(log.Fields{
				"uid":    p.User.Uid.Hex(),
				"data":   "20000",
				"method": "CardGameDesignatedEnterRequest",
			}).Error("给金币失败")
			return res, err
		}
		p.TimelyUpdateProp(req.GetType(), uProp)
		utils.AsyncFunc(func() {
			p.UpdateProp(req.GetType(), uProp)
		})
		nGuide.FirstCardMonsterGold = true
	}
	return
}
